#pragma once
#include "decode.h"
#include "encode.h"
#include "decode_vp8.h"
#include "buffer.h"

#ifdef _DEBUG
#pragma comment( lib, "libwebp_a_debug.lib" )
#else
#pragma comment( lib, "libwebp_a.lib" )
#endif

namespace umtl
{

	namespace webp
	{
		//////////////////////////////////////////////////////////////////////////
		//

		template< typename Alloc = EmptyAlloc, typename DeAlloc = DefaultFree >
		class encoder
		{
		public:
			typedef buffer< Alloc, DeAlloc > buffer;

			// Returns the size of the compressed data (pointed to by *output), or 0
			buffer operator()( unsigned char const * input, int width, int height, color_type out_format, float quality_factor = 75.0f )
			{
				size_t size=0;

				buffer buf( width, height, out_format );

				switch( out_format )
				{
				case color_type::rgb :
					size = WebPEncodeRGB( input, width, height, width * 3, quality_factor, &buf.data() );
					break;

				case color_type::bgr :
					size = WebPEncodeBGR( input, width, height, width * 3, quality_factor, &buf.data() );
					break;

				case color_type::rgba :
					size = WebPEncodeRGBA( input, width, height, width * 4, quality_factor, &buf.data() );	
					break;

				case color_type::bgra :
					size = WebPEncodeBGRA( input, width, height, width * 4, quality_factor, &buf.data() );
					break;
				}

				buf.size() = size;

				return buf;
			}
		};

		//////////////////////////////////////////////////////////////////////////
		//

		template< typename Alloc = DefaultNew, typename DeAlloc = DefaultDelete >
		class decoder
		{
		public:
			typedef buffer< Alloc, DeAlloc > buffer;

			// Returns the size of the compressed data (pointed to by *output), or 0
			buffer operator()( unsigned char const * input, unsigned int size, color_type out_format, int & out_width, int & out_height )
			{
				size_t size=0;
				unsigned char *output = 0;

				out_width = 0;
				out_height = 0;

				if( !WebPGetInfo( input, size, &out_width, &out_height ) )
					return buffer( 0, 0, out_format );

				buffer buf( out_width, out_height, out_format );

				switch( out_format )
				{
				case color_type::rgb :
					WebPDecodeRGBInto( input, size, buf.data(), buf.size(), out_width * 3 );
					break;

				case color_type::bgr :
					WebPDecodeBGRInto( input, size, buf.data(), buf.size(), out_width * 3 );
					break;

				case color_type::rgba :
					WebPDecodeRGBAInto( input, size, buf.data(), buf.size(), out_width * 4 );
					break;

				case color_type::bgra :
					WebPDecodeBGRAInto( input, size, buf.data(), buf.size(), out_width * 4 );
					break;
				}

				return buf;
			}
		};

		//////////////////////////////////////////////////////////////////////////
	}

}